package mahjong;

import java.util.*;

/**
 * Class to order move according to a specific heuristic score

 */
public class MoveOrderer
{
	/** heuristic value for the tile depth */
	private static final int DEPTHVAL = 10;
	/** heuristic value for the tile width */
	private static final int WIDTHVAL = 2;
	/** heuristic value for if removing tile will open neighbour */
	private static final int OPENBONUS = 0;

	/**
	 * Sorts moves in an array list according to a heuristic
	 * @param board board to be played on
	 * @return ArrayList of sorted moves
	 */
	public static ArrayList<Tile[]> sortMoves(Board board)
	{
		ArrayList<Tile[]> aMoves = board.getAvailableMoves();
		final int boardWidth = board.getWidth();

		Collections.sort(aMoves, new Comparator<Tile[]>() {
			@Override
			public int compare(Tile[] m1, Tile[] m2)
			{
				return scoreTile(m2[0], boardWidth) + scoreTile(m2[1], boardWidth) -
					scoreTile(m1[0], boardWidth) - scoreTile(m1[1], boardWidth);
			}
		});

		return aMoves;
	}

	/**
	 * Give a score to a specific tile
	 * @param t tile to be scored
	 * @param boardWidth width of the board
	 * @return score in int value
	 */
	public static int scoreTile(Tile t, int boardWidth)
	{
		return t.getZ() * DEPTHVAL +
			Math.abs(t.getX()+1 - boardWidth / 2) * WIDTHVAL +
			(willOpenNeighbour(t) ? OPENBONUS : 0);
	}

	/** Check if the remove of t frees up any other tiles */
	private static boolean willOpenNeighbour(Tile t)
	{
		Tile adj = t.getUpRight();
		if(adj != null) {				
			if(adj.isTopFree()) return true;					
		}

		adj = t.getUpLeft();
		if(adj != null) {				
			if(adj.isTopFree()) return true;					
		}

		adj = t.getLowerLeft();
		if(adj != null) {				
			if(adj.isTopFree()) return true;					
		}

		adj = t.getLowerRight();
		if(adj != null) {				
			if(adj.isTopFree()) return true;					
		}

		return false;
	}
}
